package com.handinfo.uimenu;

import javax.microedition.lcdui.Graphics;

import com.handinfo.engine.AbstractGameScreen;
import com.handinfo.engine.GameManager;
import com.handinfo.util.ArrayList;
import com.handinfo.util.Tools;
import com.test.touch.GameTouchManager;

/**
 * 交互菜单
 * 
 * @author venizeng
 * 
 */
public class UiInteractMenu extends UIAbstractContext
{

	private final String NAME = "name";// 名字属性
	private final String WIN = "win";// 显示属性
	private static final String TAG_START = "<dialog";// 起始标签
	private static final String TAG_END = "</dialog>";// 借书标签

	// private final int W_DEFAULT = (AbstractGameScreen.SCREEN_WIDTH >> 2) * 3;
	private final int W_DEFAULT = UITools.W_BG;
	private final int H_MAX = AbstractGameScreen.FONT_H << 2;// 最多显示四行

	/**
	 * 是否在顶端
	 */
	private boolean[] m_isUps;

	/**
	 * 对话名称
	 */
	private String[] m_names;

	/**
	 * 一句对话内容，当前暂时保留，未定显示数据
	 */
	private String[] m_contents;

	/**
	 * 对话内容的显示对象
	 */
	private Object[] m_datas;

	/**
	 * 指向第几条对话
	 */
	private int m_index;

	/**
	 * 如果所需现似乎当前文字超出屏幕则内容上移
	 */
	private int m_relY;

	/**
	 * 显示消息的高度
	 */
	private int m_h_name;

	/**
	 * 显示消息的高度
	 */
	private int m_h_rect;

	/**
	 * 显示消息的高度
	 */
	private int m_h_content;

	/**
	 * 显示消息的高度
	 */
	private int m_h_message;

	/**
	 * 如果下一行具有内容
	 */
	private int m_h_next;

	/**
	 * 显示内容的宽度
	 */
	private final int W_CONTENT;

	/**
	 * 显示框的宽度
	 */
	private final int W_RECT;

	/**
	 * 边缘到显示框的宽度
	 */
	private final int X_RECT_BORDER = 7;

	/**
	 * 显示框到内容层的宽度
	 */
	private final int X_CONTENT_RECT = 8;

	/**
	 * 边缘到显示框的高度
	 */
	private final int Y_RECT_BORDER = 7;

	/**
	 * 显示框到内容框的高度
	 */
	private final int Y_CONTENT_RECT = 6;

	/**
	 * 关闭之后调用的监听器
	 */
	private UIListener m_listener_interact;

	private String m_key;

	protected UiInteractMenu(int id)
	{
		super(id);
		m_w = W_DEFAULT;
		W_RECT = m_w - (X_RECT_BORDER << 1);
		W_CONTENT = W_RECT - (X_CONTENT_RECT << 1);
		//
		m_h_name = UITools.H_PRE + 2;
	}

	/**
	 * 开启一个交互式菜单
	 * 
	 * @param info
	 */
	public static final UiInteractMenu openInteractMenu(String key, String info)
	{
		if (!isInteractiveStr(info)) {
			throw new IllegalArgumentException("当前语句非交互式菜单语句 " + info);
		}
		UiInteractMenu interactMenu = (UiInteractMenu) UIManager.getInstance().getWindowById(
				UIWindowFactory.WINDOW_INTERACT);
		if (interactMenu == null) {
			interactMenu = (UiInteractMenu) UIWindowFactory.createWindow(UIWindowFactory.WINDOW_INTERACT);
		}
		interactMenu.setInfo(key, info);
		if ((UiInteractMenu) UIManager.getInstance().getWindowById(interactMenu.m_id) == null) {
			UIManager.getInstance().addWindow(interactMenu);
		}
		return interactMenu;
	}

	/**
	 * 设置交互框的内容 2012-3-6 上午10:56:23 venizeng
	 * @param key
	 * @param info
	 */
	public void setInfo(String key, String info)
	{
		this.m_key = key;
		this.setInteractiveStr(info);
	}

	/**
	 * 判断一段文字是否符合交互式菜单的规则 严格的<dialog>data1</dialog><dialog name = 1>data2</dialog>形式
	 * @param info
	 * @return
	 */
	private static final boolean isInteractiveStr(String info)
	{
		int startIndex = 0;
		if (info.indexOf(UiInteractMenu.TAG_START, startIndex) == -1) {// 第一个标签
			return false;
		}
		do {
			int endTagStartIndex = info.indexOf(UiInteractMenu.TAG_END, startIndex);
			if (endTagStartIndex == -1) {// 无结束标签
				return false;
			}
			startIndex = endTagStartIndex + UiInteractMenu.TAG_END.length();
		}
		while (startIndex == info.indexOf(UiInteractMenu.TAG_START, startIndex));// 开始标记就应该是上一结束标记的末尾索引+1
		return startIndex == info.length();
	}

	/**
	 * 将符合交互式菜单的字符串进行解析，并将其放置到交互式菜单中
	 * 
	 * @param info
	 */
	private void setInteractiveStr(String info)
	{
		clean();
		//
		if (AbsHyperLinker.isHyperLink(info)) {
			info = AbsHyperLinker.replaceContent(info);
		}
		m_contents = getSplitStr(info);
		int size = m_contents == null ? 0 : m_contents.length;
		if (size == 0) {
			return;
		}
		m_isUps = new boolean[size];
		m_names = new String[size];
		m_datas = new Object[size];// 显示
		for (int i = 0; i < size; i++) {
			m_isUps[i] = getIsUp(m_contents[i]);
			m_names[i] = getName(m_contents[i]);
			String content = getContent(m_contents[i]);
			if (AbsHyperLinker.isHyperLink(content)) {
				AbsHyperLinker hyperLinker = AbsHyperLinker.createHyperLinker(content, W_CONTENT - 1, 200);
				hyperLinker.setH(hyperLinker.getRealHeight());
				m_datas[i] = hyperLinker;
			}
			else {
				m_datas[i] = Tools.getStrArray(content, W_CONTENT - 1);
			}
		}
		//
		init();
	}

	/**
	 * 再次设置的时候需清理当前变量 2012-2-15 上午09:42:35 venizeng
	 */
	private void clean()
	{
		m_isUps = null;
		m_names = null;
		m_contents = null;
		m_datas = null;
		m_index = 0;

		m_relY = 0;
		//
		m_h_rect = 0;
		m_h_content = 0;
		m_h_next = 0;
	}

	/**
	 * 初始化当前变量 2012-2-15 上午09:48:59 venizeng
	 */
	private void init()
	{
		if (m_datas[m_index] == null) {
			return;
		}
		// int h = ((String[]) m_datas[m_index]).length * UITools.H_PRE;
		// m_h_message = h >= H_MAX ? H_MAX : H_MAX;
		m_h_message = H_MAX;
		m_h_next = isGotNext() ? UITools.H_PRE : 0;
		m_h_content = m_h_name + m_h_message + m_h_next;
		m_h_rect = m_h_content + (Y_CONTENT_RECT << 1);
		m_h = m_h_rect + (Y_RECT_BORDER << 1);
		setXY();
	}

	/**
	 * 当每次换对话框的时候重置位置信息 2012-2-15 上午10:11:44 venizeng
	 */
	private void setXY()
	{
		if (m_isUps == null) {
			return;
		}
		int IW = UITools.INITX_CONTENT;
		if (m_isUps[m_index]) {
			m_x = IW;
			m_y = UITools.IH_RECT_CONTENT;
		}
		else {
			m_x = AbstractGameScreen.SCREEN_WIDTH - m_w - IW;
			m_y = AbstractGameScreen.SCREEN_HEIGHT - m_h - UITools.IH_RECT_CONTENT - UITools.H_PRE;
		}
	}

	private boolean isGotNext()
	{
		if (m_isUps == null) {
			return false;
		}
		if (m_index >= (m_isUps.length - 1) || m_index < 0) {
			return false;
		}
		return true;
	}

	/**
	 * 获得切割的字符串數組
	 * @param info
	 * @return
	 */
	private String[] getSplitStr(String info)
	{
		int startIndex = 0;
		ArrayList list = new ArrayList();
		String temp = null;
		while ((startIndex = info.indexOf(TAG_START, startIndex)) != -1) {
			temp = null;
			temp = getSplitStr(info, startIndex);
//			if (temp != null) {
//				System.err.println("SplitStr-->" + temp + "<--");
//			}
			list.addElement(temp);
			startIndex++;
		}
		int size = list.size();
		if (size == 0) {
			throw new IllegalArgumentException("内容错误 info = " + info);
		}
		String[] splits = new String[size];
		for (int i = size - 1; i >= 0; i--) {
			splits[i] = (String) list.elementAt(i);
		}
		return splits;
	}

	/**
	 * 获得分割字符串
	 * @param info
	 * @param startIndex
	 * @return
	 */
	private String getSplitStr(String info, int startIndex)
	{
		int realStartIndex = startIndex;// 判断
		int endIndex = getEndTagStartIndex(info, realStartIndex) + TAG_END.length();
		return info.substring(realStartIndex, endIndex);
	}

	/**
	 * 获得起始标签结束标签“>”的索引 <dialog>对话内容</dialog> <dialog win=1/2>对话内容</dialog> <dialog name=nameX>对话内容</dialog> <dialog
	 * win=1/2 name=nameX>对话内容</dialog>
	 * 
	 * @param info
	 */
	private int getStartTagEndIndex(String splitStr)
	{
		return splitStr.indexOf(">");
	}

	/**
	 * 获得结束标签的起始位置"</dialog>" <dialog>对话内容</dialog><dialog win=1/2>对话内容</dialog> <dialog name=nameX>对话内容</dialog>
	 * <dialog win=1/2 name=nameX>对话内容</dialog>
	 * @param str
	 * @param startIndex
	 * @return
	 */
	private int getEndTagStartIndex(String str, int startIndex)
	{
		return str.indexOf(TAG_END, startIndex);
	}

	/**
	 * 获得切割的内容
	 * @param splitStr
	 * @return
	 */
	private String getContent(String splitStr)
	{
		int startTagEndIndex = getStartTagEndIndex(splitStr) + 1;// ">"结束标志的索引
		int endTagStartIndex = getEndTagStartIndex(splitStr, startTagEndIndex);
		return splitStr.substring(startTagEndIndex, endTagStartIndex);
	}

	/**
	 * 从分割的字符串中获得当前是否在顶部显示 <dialog>对话内容</dialog> <dialog win=1/2>对话内容</dialog> <dialog name=nameX>对话内容</dialog> <dialog
	 * win=1/2 name=nameX>对话内容</dialog>
	 * 
	 * @param splitStr
	 * @return
	 */
	private boolean getIsUp(String splitStr)
	{
		int winIndex = splitStr.indexOf(WIN);
		int endIndex = getStartTagEndIndex(splitStr);// ">"结束标志的索引
		if (winIndex == -1) {// 未写入显示位置或超出了<dialog>头标签范围(即当做内容传入)
			return true;
		}
		else if (winIndex >= endIndex) {
			return true;
		}
		else if (splitStr.charAt(winIndex + WIN.length() + 1) == '1') {
			return true;
		}
		return false;
	}

	/**
	 * 从分割的字符串中获得当前名字 <dialog>对话内容</dialog> <dialog win=1/2>对话内容</dialog> <dialog name=nameX>对话内容</dialog> <dialog
	 * win=1/2 name=nameX>对话内容</dialog>
	 * 
	 * @param splitStr
	 * @return
	 */
	private String getName(String splitStr)
	{
		int nameIndex = splitStr.indexOf(NAME);
		int endIndex = getStartTagEndIndex(splitStr);// ">"结束标志的索引
		if (nameIndex == -1 || nameIndex >= endIndex) {// 未写入名字或超出了<dialog>头标签范围(即当做内容传入)
			return GameManager.getInstance().m_role.m_name;
		}
		return splitStr.substring(nameIndex + NAME.length() + 1, endIndex);
	}

	protected void paintContent(Graphics g)
	{
		int tempX = m_x;
		int tempY = m_y;
		UITools.drawWindowBackgroud(g, m_x, m_y, m_w, m_h);
		// UITools.drawWindowBackgroud(g, m_x, m_y, m_w, m_h);
		tempX += X_RECT_BORDER;
		tempY += Y_RECT_BORDER;
		// UITools.paintContentRect(g, tempX, tempY, W_RECT, m_h_rect);
		tempX += X_CONTENT_RECT;
		tempY += Y_CONTENT_RECT;
		paintName(g, tempX, tempY);
		tempY += m_h_name;
		paintDialog(g, tempX, tempY, W_CONTENT, m_h_message);
		tempY += m_h_message;
		paintNext(g, m_x + m_w - (X_RECT_BORDER + X_RECT_BORDER), tempY);
		paintJiaobiao(g);
	}

	/**
	 * 2012-2-20 上午10:45:53 venizeng
	 * @param g
	 */
	private void paintJiaobiao(Graphics g)
	{
		// int tempX =
		// g.drawImage(UITools.IMAGE_JIAOBIAO, arg1, arg2, arg3)
	}

	private void paintName(Graphics g, int x, int y)
	{
		if (m_names == null || m_names[m_index] == null) {
			return;
		}
		g.setColor(0xfb8a8b);
		g.drawString(m_names[m_index], x, y, 0);
//		if (m_isUps[m_index]) {
//		}
//		else {
//			g.setColor(0x8afbe8);
//			g.drawString(m_names[m_index], m_x + m_w - (X_RECT_BORDER + X_CONTENT_RECT), y, Tools.RIGHT_TOP);
//		}
	}

	private void paintDialog(Graphics g, int x, int y, int w, int h)
	{
		if (m_datas == null || m_datas[m_index] == null) {
			return;
		}
		int clipX = g.getClipX();
		int clipY = g.getClipY();
		int clipW = g.getClipWidth();
		int clipH = g.getClipHeight();
		g.setClip(x, y, w, h);
		if (m_datas[m_index] instanceof AbsHyperLinker) {
			AbsHyperLinker hyperLinker = (AbsHyperLinker) m_datas[m_index];
			hyperLinker.paint(g, x, y + m_relY);
		}
		else {
			paintStrs(g, x, y, w, h);
		}
		g.setClip(clipX, clipY, clipW, clipH);
	}

	private void paintStrs(Graphics g, int x, int y, int w, int h)
	{
		String[] strs = (String[]) m_datas[m_index];
		g.setColor(UIManager.getPaletteColor(UIManager.COLOR_WORD_YESS));
		int tempY = y + m_relY;
		final int LASTY = y + h;
		for (int i = 0, length = strs.length; i < length; i++) {
			if (tempY < y) {// 顶部超屏
				tempY += AbstractGameScreen.FONT_H;
			}
			else if (tempY >= LASTY) {// 底部超屏
				break;
			}
			else {
				g.drawString(strs[i], x, tempY, 0);
				tempY += AbstractGameScreen.FONT_H;
			}
		}
	}

	private int m_time_next_move;
	private int m_time_next_color;
	private boolean m_move_next = true;
	private boolean m_color_next;

	private void paintNext(Graphics g, int x, int y)
	{
		// if (!isGotNext()) {
		// return;
		// }
		if (m_time_next_color == 0) {
			m_color_next = !m_color_next;
		}
		if (m_time_next_color >= 1) {
			m_time_next_color = 0;
		}
		else {
			m_time_next_color++;
		}

		if (m_move_next) {
			if (m_time_next_move >= 2) {
				m_move_next = false;
			}
			else {
				m_time_next_move++;
			}
		}
		else {
			if (m_time_next_move <= 0) {
				m_move_next = true;
			}
			else {
				m_time_next_move--;
			}
		}
		y += m_time_next_move;

		x -= 15;
		int iw = 2;
		int w = 8;
		int h = 4;
		int color_out = 0x4d0303;
		int color_in_top = 0x9dfb9f;
		int color_in_bottom = 0x54c651;
		UITools.drawRect(g, x, y, w, h, color_out, 0);
		if (m_color_next) {
			UITools.fillRect(g, x, y, w, h, color_in_top, 1);
		}
		else {
			UITools.fillRect(g, x, y, w, h, color_in_bottom, 1);
		}
		y += 1;
		int x1 = x - iw;
		int y_top = y + h;
		int x2 = x + w + iw;
		int x3 = x + (w >> 1);
		int y_bottom = y_top + 6;
		if (m_color_next) {
			g.setColor(color_in_bottom);
		}
		else {
			g.setColor(color_in_top);
		}
		g.fillTriangle(x1, y_top, x2, y_top, x3, y_bottom);
		g.setColor(color_out);
		g.drawLine(x1, y_top, x2, y_top);
		g.drawLine(x1, y_top, x3, y_bottom);
		g.drawLine(x2, y_top, x3, y_bottom);

	}

	public void addListener(UIListener listener)
	{
		m_listener_interact = listener;
	}

	protected void keyLogic()
	{
		//屏蔽方向键
		if (AbstractGameScreen.haveKeyPressed(AbstractGameScreen.GK_UP)) {
			return ;
		}
		else if (AbstractGameScreen.haveKeyPressed(AbstractGameScreen.GK_DOWN)) {
			return ;
		}
		else if (AbstractGameScreen.haveKeyPressed(AbstractGameScreen.GK_LEFT)) {
			return ;
		}
		else if (AbstractGameScreen.haveKeyPressed(AbstractGameScreen.GK_RIGHT)) {
			return ;
		}
		else if (AbstractGameScreen.anyKeyPressed()) {
			if (m_datas == null || m_datas[m_index] == null) {
				return;
			}
			int H = 0;
			if (m_datas[m_index] instanceof AbsHyperLinker) {
				AbsHyperLinker hyperLinker = (AbsHyperLinker) m_datas[m_index];
				H = hyperLinker.getRealHeight() - m_h_content;
			}
			else {
				H = ((String[]) m_datas[m_index]).length * UITools.H_PRE;
			}
			int preY = H - m_h_content;// 预期值
			preY = preY > 0 ? -preY : 0;
			if (m_relY < preY) {// 内容未全部显示
				m_relY -= UITools.H_PRE;
				return;
			}
			if (isGotNext()) {
				m_index++;
				m_relY = 0;//
				setXY();
			}
			else {
				close();
				if (m_listener_interact != null) {
					m_listener_interact.actionPerformed();
				}
				// 发送m_key
				if (m_key != null) {
					GameManager.getInstance().m_game_message.sendInteractId(m_key);
				}
			}
		}
	}

	protected void registerTouch() {
		clearAllRects();
		initTouchRect(new int[][]{
				{0, 0, AbstractGameScreen.SCREEN_WIDTH, AbstractGameScreen.SCREEN_HEIGHT},
		});
	}

	protected void onTouchRect(int[][] rect, int touchid) {
		GameTouchManager.keyPressedFire();
	}

	
}
